package com.javasm.adminapi.module.product.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.javasm.adminapi.common.exception.ExceptionEnum;
import com.javasm.adminapi.common.exception.JavasmException;
import com.javasm.adminapi.module.product.QueryVo;
import com.javasm.adminapi.module.product.dao.TSpuDao;
import com.javasm.adminapi.module.product.entity.TBrand;
import com.javasm.adminapi.module.product.entity.TCategory;
import com.javasm.adminapi.module.product.entity.TSpu;
import com.javasm.adminapi.module.product.service.TBrandService;
import com.javasm.adminapi.module.product.service.TCategoryService;
import com.javasm.adminapi.module.product.service.TSpuService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * SPU 商品表(TSpu)表服务实现类
 *
 * @author makejava
 * @since 2025-10-14 22:29:07
 */
@Service("tSpuService")
public class TSpuServiceImpl extends ServiceImpl<TSpuDao, TSpu> implements TSpuService {
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Override
    public List<TSpu> getList() {
        List<TSpu> list = this.list();
        return list;
    }
    @Resource
    TBrandService tBrandService;
    @Resource
    TCategoryService tCategoryService;
    @Resource
    TSpuDao tSpuDao;
    @Override
    public PageInfo<TSpu> listByPage(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<TSpu> listAll = tSpuDao.selectAll();
        return new PageInfo<>(listAll);

    }

    @Override
    public PageInfo<TSpu> queryByInfo(QueryVo vo) {
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        LambdaQueryWrapper<TSpu> queryWrapper = new LambdaQueryWrapper<>();
        String name = vo.getName();
        if (name!=null){
            queryWrapper.and(i->{
                i.like(TSpu::getSpuName,name);
                i.or();
                i.like(TSpu::getSpuNo,name);
            });
        }
        // 分类
        Integer categoryId = vo.getCategoryId();
        if (categoryId!=null){
            queryWrapper.and(i->{
                i.eq(TSpu::getCategoryId,categoryId);
            });
        }
        //根据二级分类
        Integer secondCategoryId = vo.getSecondCategoryId();
        if (secondCategoryId!=null){
            queryWrapper.and(i->{
                i.eq(TSpu::getSecondCategoryId,secondCategoryId);
            });
        }
        //品牌
        Integer brandId = vo.getBrandId();
        if (brandId!=null){
            queryWrapper.and(i->{
                i.eq(TSpu::getBrandId,brandId);
            });
        }
        //状态
        Integer status = vo.getStatus();
        if (status!=null){
            queryWrapper.and(i->{
                i.eq(TSpu::getStatus,status);
            });
        }
        //时间
        String start = vo.getStartTime();
        String end = vo.getEndTime();
        if (!StringUtils.isEmpty(start)&&!StringUtils.isEmpty(end)){
            queryWrapper.and(i->{
                i.between(TSpu::getCreatedTime,start,end);
//                i.apply("date_format(reg_time,'%Y-%m-%d') BETWEEN {0} AND {1}",start,end);
            });
        }
        queryWrapper.and(i->{
            i.eq(TSpu::getIsDeleted,0);
        });
        queryWrapper.orderByDesc(TSpu::getId);
        List<TSpu> list = this.list(queryWrapper);

        List<TCategory> tCategoryList = tCategoryService.list();
        Map<Integer,String> tCategorymap = new HashMap<>();
        tCategoryList.forEach(tCategory -> {
            tCategorymap.put(Integer.parseInt(tCategory.getId()),tCategory.getCategoryName());
        });
        List<TBrand> tBrandList = tBrandService.list();
        Map<Integer,String> tBrandmap = new HashMap<>();
        tBrandList.forEach(tBrand -> {
            tBrandmap.put(Integer.parseInt(String.valueOf(tBrand.getId())),tBrand.getBrandName());
        });
        list.forEach(tSpu -> {
            tSpu.setCategoryName(tCategorymap.get(Integer.parseInt(tSpu.getCategoryId())));
            tSpu.setBrandName(tBrandmap.get(Integer.parseInt(tSpu.getBrandId())));
        });

        return new PageInfo<>(list);
    }

        /**
     * 添加商品SPU信息
     * @param tSpu 商品SPU对象，包含商品的基本信息
     * @return Boolean 添加成功返回true，失败则抛出异常
     */
    @Override
    public Boolean addTSput(TSpu tSpu) {
        // 生成唯一的SPU编号
        String newSpuNo = generateUniqueSpuNoWithTimestamp();
        tSpu.setSpuNo(newSpuNo);

        // 获取商品分类信息并设置一级分类相关信息
        TCategory byId = tCategoryService.getById(tSpu.getCategoryId());
        tSpu.setFirstCategoryId(Long.valueOf(byId.getId()));
        tSpu.setFirstCategoryName(byId.getCategoryName());

        // 设置创建时间并保存商品SPU信息
        tSpu.setCreatedTime(new Date());
        boolean save = this.save(tSpu);
        if (!save){
            throw new JavasmException(ExceptionEnum.SQL_Error);
        }else {
            return save;
        }
    }


        /**
     * 根据ID更新商品SPU信息
     * @param tSpu 包含更新信息的商品SPU对象，必须包含有效的ID
     * @return 更新成功返回true，更新失败抛出异常
     * @throws JavasmException 当商品SPU不存在或更新失败时抛出对应异常
     */
    @Override
    public Boolean updateByIdinfo(TSpu tSpu) {
        //通过id查询原商品SPU信息，用于验证商品是否存在
        TSpu tSpu1 = this.getById(tSpu.getId());
        if (tSpu1==null){
            throw new JavasmException(ExceptionEnum.Spu_Not_Exist);
        }
        //设置更新时间并执行更新操作
        tSpu.setUpdatedTime(new Date());
        boolean update = this.updateById(tSpu);
        if (!update){
            throw new JavasmException(ExceptionEnum.Spu_Upadate_Error);
        }
        return update;
    }


    /**
     * 生成唯一的SPU编号
     * @return 唯一的SPU编号
     */
    // 更高效的实现方式
    private String generateUniqueSpuNoWithTimestamp() {
        // 使用时间戳+随机数的方式，减少碰撞概率
        long timestamp = System.currentTimeMillis() % 100000000;
        int random = (int) (Math.random() * 100);
        return String.format("SPU%08d%02d", timestamp, random);
    }


}

